{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Example of heatmap generation\n",
    "This notebook shows an example of heatmap label generation for DHP19 dataset. \n",
    "Run the notebook after generating the DHP19 accumulated images/labels (in .h5 format) from the .aedat recordings and .mat 3D joint positions labels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import h5py\n",
    "import numpy as np\n",
    "from os.path import join\n",
    "import matplotlib.pyplot as plt\n",
    "import cv2\n",
    "\n",
    "def load_file_(filepath):\n",
    "    if filepath.endswith('.h5'):\n",
    "        with h5py.File(filepath, 'r') as f_:\n",
    "            data = (f_[list(f_.keys())[0]])[()]\n",
    "    else:\n",
    "        raise ValueError('.h5 required format.')\n",
    "    return data\n",
    "\n",
    "def decay_heatmap(heatmap, sigma2=4):\n",
    "    heatmap = cv2.GaussianBlur(heatmap,(0,0),sigma2)\n",
    "    heatmap /= np.max(heatmap) # to keep the max to 1\n",
    "    return heatmap"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Change the paths and parameters in the next cell "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# path of files generated using matlab \n",
    "path_ = ''\n",
    "# camera projection matrices path\n",
    "P_mat_dir = ''\n",
    "\n",
    "image_h, image_w, num_joints = 260, 346, 13 # depend on how accumulated frames are generated in Matlab\n",
    "\n",
    "t  = 19 # timestep of image to plot\n",
    "subj, sess, mov = 2, 4, 6\n",
    "decay_maps_flag = True # True to blur heatmaps\n",
    "ch_idx = 3 # 0 to 3. This is the order of channels in .aedat/.h5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "NB: the order of channels in the .aedat file (and in the saved .h5) is different from the camera index. \n",
    "The next cell takes care of this, loading the proper camera projection matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "if ch_idx==1:\n",
    "    P_mat_cam = np.load(join(P_mat_dir,'P1.npy'))\n",
    "elif ch_idx==3:\n",
    "    P_mat_cam = np.load(join(P_mat_dir,'P2.npy'))\n",
    "elif ch_idx==2:\n",
    "    P_mat_cam = np.load(join(P_mat_dir,'P3.npy'))\n",
    "elif ch_idx==0:\n",
    "    P_mat_cam = np.load(join(P_mat_dir,'P4.npy'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "load files of images and labels, and select the single sample t to plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "vicon_xyz_all = load_file_(join(path_, 'S{}_session{}_mov{}_7500events_label.h5'.format(subj,sess,mov)))\n",
    "images_all = load_file_(join(path_, 'S{}_session{}_mov{}_7500events.h5'.format(subj,sess,mov)))\n",
    "vicon_xyz = vicon_xyz_all[t]\n",
    "image = images_all[t, :, :, ch_idx]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Algorithm to convert XYZ Vicon coordinates to UV pixel coordinates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# use homogeneous coordinates representation to project 3d XYZ coordinates to 2d UV pixel coordinates.\n",
    "vicon_xyz_homog = np.concatenate([vicon_xyz, np.ones([1,13])], axis=0)\n",
    "coord_pix_all_cam2_homog = np.matmul(P_mat_cam, vicon_xyz_homog)\n",
    "coord_pix_all_cam2_homog_norm = coord_pix_all_cam2_homog/coord_pix_all_cam2_homog[-1]\n",
    "u = coord_pix_all_cam2_homog_norm[0]\n",
    "v = image_h - coord_pix_all_cam2_homog_norm[1] # flip v coordinate to match the image direction\n",
    "\n",
    "# mask is used to make sure that pixel positions are in frame range.\n",
    "mask = np.ones(u.shape).astype(np.float32)\n",
    "mask[u>image_w] = 0\n",
    "mask[u<=0] = 0\n",
    "mask[v>image_h] = 0\n",
    "mask[v<=0] = 0\n",
    "\n",
    "# pixel coordinates\n",
    "u = u.astype(np.int32)\n",
    "v = v.astype(np.int32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Generate the heatmaps and plot them over the image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# initialize the heatmaps\n",
    "label_heatmaps = np.zeros((image_h, image_w, num_joints))\n",
    "\n",
    "k = 2 # constant used to better visualize the joints when not using decay\n",
    "\n",
    "for fmidx,pair in enumerate(zip(v,u, mask)):\n",
    "    if decay_maps_flag:\n",
    "        if pair[2]==1: # write joint position only when projection within frame boundaries\n",
    "            label_heatmaps[pair[0],pair[1], fmidx] = 1\n",
    "            label_heatmaps[:,:,fmidx] = decay_heatmap(label_heatmaps[:,:,fmidx])\n",
    "    else:\n",
    "        if pair[2]==1: # write joint position only when projection within frame boundaries\n",
    "            label_heatmaps[(pair[0]-k):(pair[0]+k+1),(pair[1]-k):(pair[1]+k+1), fmidx] = 1\n",
    "\n",
    "plt.figure()\n",
    "plt.imshow(image, cmap='gray')\n",
    "plt.imshow(np.sum(label_heatmaps, axis=-1), alpha=.5)\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
